package com.zhanghao.sdk.base;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.support.annotation.NonNull;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;

import com.zhanghao.sdk.R;
import com.zhanghao.sdk.util.ZHLog;

import java.util.Objects;

public class BaseDialog extends Dialog implements View.OnClickListener, DialogInterface.OnKeyListener {
    protected Context mContext;
    protected View mLyout;

    public BaseDialog(@NonNull Context context) {
        super(context, R.style.ZHCustomDialog);
        // 初始化配置
        initConfig();
        // 绑定子类的布局
        bindLayout();
        // 初始化视图
        initView();
    }

    /**
     * 绑定布局
     */
    protected void bindLayout() {

    }

    /**
     * 绑定布局
     * 给子类使用的
     *
     * @param layoutId 布局id
     */
    protected void bindLayout(int layoutId) {
        setContentView(layoutId);
        mLyout = Objects.requireNonNull(getWindow()).getDecorView();
    }

    /**
     * 初始化视图
     */
    protected void initView() {
        mContext = getContext();
    }

    private void initConfig() {
        // 监听键盘事件
        setOnKeyListener(this);
        // 点击空白处不关闭dialog
        setCancelable(false);
        // 设置键盘弹起后不挤压布局尺寸
        Objects.requireNonNull(getWindow()).setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
    }

    @Override
    public void onClick(View v) {
        // 所有的点击事件在这里触发
    }

    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            return onBackKey();
        }
        return false;
    }

    /**
     * 监听返回键的事件
     *
     * @return true 拦截关闭dialog的动作，否则不进行拦截
     */
    protected boolean onBackKey() {
        return true;
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        // 点击弹窗外部区域
        if (isOutOfBounds(mContext, event)) {
            // 判断键盘是否弹起,如果是的则关闭键盘,否则不处理
            if (isSHowKeyboard(mContext, mLyout)) {
                hideKeyboard(mContext, mLyout);
            }
        }
        return super.onTouchEvent(event);
    }

    /**
     * 判断触摸坐标是否在空白区域
     *
     * @param context 上下文
     * @param event   事件
     * @return 如果返回true在边框外部, 否则就是在内部.
     */
    private boolean isOutOfBounds(Context context, MotionEvent event) {
        try {
            final int x = (int) event.getX();// 相对弹窗左上角的x坐标
            final int y = (int) event.getY();// 相对弹窗左上角的y坐标
            final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();//最小识别距离
            final View decorView = mLyout;// 弹窗的根View
            return (x < -slop) || (y < -slop) || (x > (decorView.getWidth() + slop))
                    || (y > (decorView.getHeight() + slop));
        } catch (Exception e) {
            ZHLog.e(e.getMessage());
        }
        return false;
    }

    /**
     * 判断软键盘是否弹出
     *
     * @param context 上下文
     * @param v       检测的View
     * @return 如果返回true, 说明键盘弹起了, 否则就是没有弹起.
     */
    private boolean isSHowKeyboard(Context context, View v) {
        try {
            InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
            assert imm != null;
            if (imm.hideSoftInputFromWindow(v.getWindowToken(), 0)) {
                imm.showSoftInput(v, 0);
                return true;
                //软键盘已弹出
            } else {
                return false;
                //软键盘未弹出
            }
        } catch (Exception e) {
            ZHLog.e(e.getMessage());
        }
        return false;
    }

    /**
     * 关闭软键盘
     *
     * @param context 上下文
     * @param view    需要关闭的View
     */
    private void hideKeyboard(Context context, View view) {
        try {
            InputMethodManager manager = ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE));
            if (manager != null) {
                manager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            }
        } catch (Exception e) {
            ZHLog.e(e.getMessage());
        }
    }
}
